// 1. 导入依赖：HTTP请求工具与错误提示组件
import axios from 'axios';
import { ElMessage } from 'element-plus';

// 2. 创建axios实例：隔离全局配置，避免污染
// 独立实例可自定义基础路径、超时时间，适配不同环境需求
const request = axios.create({
  // 基础请求路径：读取环境变量（.env文件配置，如开发环境VITE_APP_BASE_API=/api）
  // 不同环境（开发/生产）可通过.env文件切换，无需修改代码
  baseURL: import.meta.env.VITE_APP_BASE_API,
  // 请求超时时间：5秒内无响应则判定为超时，触发错误处理
  timeout: 5000,
});

// 3. 请求拦截器：请求发送前的统一预处理
// 拦截所有通过该实例发送的请求，可添加公共参数、token等
request.interceptors.request.use(
  config => {
    // config：请求配置对象，包含接口地址、请求方式、请求头、请求参数等
    // 预留扩展入口：
    // - 如添加token：config.headers.token = localStorage.getItem('token')
    // - 如设置请求头：config.headers['Content-Type'] = 'application/json'
    // - 如显示加载中状态：可在此处调用loading组件

    // 必须返回config，否则请求会中断
    return config;
  },
  // 请求发送前的错误处理（如参数配置错误）
  error => {
    // 将错误抛出，供调用时通过catch捕获处理
    return Promise.reject(error);
  }
);

// 4. 响应拦截器：请求返回后的统一处理
// 分“HTTP成功响应（2xx状态码）”和“HTTP失败响应（非2xx状态码）”处理
request.interceptors.response.use(
  // 处理HTTP成功响应：提取数据并判断业务逻辑
  response => {
    // 提取接口返回的核心数据，避免后续调用时重复写.response.data
    const res = response.data;

    // 第一步：判断是否为“用户名/密码错误”（按后端约定标识匹配）
    // 场景1：后端用特定code标识（如201=账号密码错误，需和后端确认）
    // 场景2：后端用message关键词标识（如含“账号”“密码”的提示文本）
    const isPwdError =
      res.code === 201 ||
      (res.message && (res.message.includes('账号') || res.message.includes('密码')));

    // 第二步：账号密码错误时，自动弹出提示并抛出错误
    if (isPwdError) {
      // 优先用后端返回的提示文本，无则用默认文案，引导用户检查账号密码
      ElMessage({
        type: 'error',
        message: res.message || '用户名或密码不正确，请重新输入',
      });
      // 抛出错误，让调用时进入catch回调（避免误当作成功处理）
      return Promise.reject(new Error(res.message || '账号密码验证失败'));
    }

    // 第三步：处理其他业务错误（如验证码过期、参数无效等，code≠200）
    if (res.code !== 200) {
      // 统一提示业务错误，无后端文本时用默认文案
      ElMessage({
        type: 'error',
        message: res.message || '操作失败，请重试',
      });
      // 抛出错误，供调用时捕获处理
      return Promise.reject(new Error(res.message || '业务请求失败'));
    }

    // 第四步：业务成功（code=200），返回核心数据（简化后续调用层级）
    // 示例：调用request.get('/api/user/info')时，then回调的res直接是接口返回的data
    return res.data;
  },
  // 处理HTTP失败响应：如404（接口不存在）、500（服务器错误）、网络断开等
  error => {
    // 存储错误提示文本，根据不同错误场景定义
    let msg = '';
    // 提取HTTP状态码：网络错误时error.response为undefined，用可选链避免报错
    const status = error.response?.status;

    // 按HTTP状态码分类定义提示文本，让用户清晰知道错误原因
    switch (status) {
      case 401:
        msg = 'token过期或未登录，请重新登录'; // 身份验证失效
        // 预留扩展：如清除无效token、跳转登录页
        // localStorage.removeItem('token');
        // window.location.href = '/login';
        break;
      case 403:
        msg = '无权访问，您没有该操作的权限'; // 权限不足
        break;
      case 404:
        msg = '请求地址错误，接口不存在'; // 接口路径错误
        break;
      case 500:
        msg = '服务器出现问题，请稍后重试'; // 服务器内部错误
        break;
      default:
        msg = '无网络连接或请求超时，请检查网络'; // 网络错误/超时
    }

    // 显示HTTP错误提示，红色警告样式醒目
    ElMessage({
      type: 'error',
      message: msg,
    });

    // 将错误抛出，供调用时通过catch捕获（如需要自定义错误处理）
    return Promise.reject(error);
  }
);

// 5. 导出axios实例：供项目中其他组件/模块调用
export default request;
